﻿using Autodesk.AutoCAD.Internal;
using System.Collections.Generic;

namespace XYCAM.CadEngine.Command;

/// <summary>
/// 命令数据基类
/// </summary>
/// <param name="command">原始的命令</param>
public class XyCommandDto(string command)
{
    /// <summary>
    /// 全局的命令字典,在这里防止重复的命令名
    /// </summary>
    private static readonly Dictionary<string, XyCommandDto> m_CommandDictionary = [];

    /// <summary>
    /// cad执行函数委托
    /// </summary>
    private CommandCallback? commandCallback;

    /// <summary>
    /// 命令重复时的回调函数
    /// </summary>
    private Func<bool>? onCommandRepeatCallback;

    /// <summary>
    /// 原始命令,这个数据是只读的
    /// </summary>
    public string Command { get; } = command;

    /// <summary>
    /// 快速命令字符字段
    /// </summary>
    private string m_quickCommand = string.Empty;

    /// <summary>
    /// 快速命令字符
    /// </summary>
    public string QuickCommand
    {
        get { return m_quickCommand; }
        set
        {
            //值相同不做任何处理,下面的逻辑中可能存在弹窗,所以这里直接跳出
            if (m_quickCommand == value)
            {
                return;
            }
            //移除CAD中的命令
            RemoveCommand(m_quickCommand);
            //清空命令字符不需要逻辑判断
            if (value is "")
            {
                m_quickCommand = value;
                return;
            }
            //如果有重复的,会返回false,则不做任何变化,不赋值
            if (AddCommand(value, commandCallback!))
            {
                m_quickCommand = value;
            }
        }
    }

    /// <summary>
    /// 设置cad执行函数委托
    /// </summary>
    /// <param name="commandCallback"></param>
    public void SetCommandCallback(CommandCallback commandCallback)
    {
        this.commandCallback = commandCallback;
    }

    /// <summary>
    /// 设置命令重复时的回调函数
    /// </summary>
    /// <param name="func"></param>
    public void SetOnCommandRepeatCallback(Func<bool> onCommandRepeatCallback)
    {
        this.onCommandRepeatCallback = onCommandRepeatCallback;
    }

    /// <summary>
    /// 添加新的命令,并注册到CAD
    /// </summary>
    /// <param name="newCommandString">新的命令字符</param>
    /// <param name="commandCallback">命令回调函数</param>
    /// <returns>是否成功</returns>
    protected virtual bool AddCommand(string newCommandString, CommandCallback commandCallback)
    {
        //如果全局字典中存在相同的命令字符
        if (m_CommandDictionary.TryGetValue(newCommandString, out XyCommandDto oldNode))
        {
            //若返回false,跳过操作
            if (!onCommandRepeatCallback!())
            {
                return false;
            }
            //直接覆盖全局字典中的对应命令功能
            m_CommandDictionary[newCommandString] = this;
            //将原有元素的命令清空
            oldNode.QuickCommand = string.Empty;
        }
        else
        {
            //不为空字符才加入全局命令字典
            m_CommandDictionary.Add(newCommandString, this);
        }

        //移除同名命令
        Autodesk.AutoCAD.Internal.Utils.RemoveCommand(newCommandString, newCommandString);
        //向CAD注册命令
        Autodesk.AutoCAD.Internal.Utils.AddCommand(newCommandString, newCommandString, newCommandString, CommandFlags.Redraw, commandCallback);

        return true;
    }

    /// <summary>
    /// 移除旧的元素,并注销CAD命令
    /// </summary>
    /// <param name="oldCommand"></param>
    protected virtual void RemoveCommand(string oldCommand)
    {
        if (oldCommand is not "")
        {
            Autodesk.AutoCAD.Internal.Utils.RemoveCommand(oldCommand, oldCommand);
        }
    }

}
